package model.util;

public abstract class Object3D {

    /** Attributs */
    private Vector3D m_position;
    private Shape3D m_shape3d;

    /** Constructeurs */
    public Object3D(Shape3D shape3d)
    { this(shape3d, new Vector3D(0.0, 0.0, 0.0)); }
    
    public Object3D(Shape3D shape3d, Vector3D position) {
        m_shape3d = shape3d;
        m_position = position;
    }

    /** Accesseurs */
    public Vector3D getPosition() { return m_position; }
    public Shape3D getShape() { return m_shape3d; }

    /** Methodes */
    public double distance(Object3D object3d) 
    { return getPosition().distance(object3d.getPosition()); }

    public double squareDistance(Object3D object3d) 
    { return getPosition().squareDistance(object3d.getPosition()); }

    public boolean intersects(Object3D object3D) 
    { return m_shape3d.intersects(m_position,object3D); }

    /** Type internes */
    public static abstract class Shape3D {

        /** Attributs */
        private Vector3D m_wrapSize, m_gravityCenter;

        /** Constructeurs */
        public Shape3D(Vector3D wrapSize, Vector3D gravityCenter) {
            m_wrapSize = wrapSize;
            m_gravityCenter = gravityCenter;
        }

        /** Accesseurs */
        public Vector3D getWrapSize() { return m_wrapSize; }
        public Vector3D getGravityCenter() { return m_gravityCenter; }

        /** Predicats */
        public boolean intersects(Vector3D position, Object3D object3D) {
            Vector3D d = position.sub(object3D.getPosition());
            Vector3D x = m_wrapSize.add(object3D.getShape().getWrapSize());            
            return d.abs().lowerThan(x.divide(2));
        }
    }
}